// EG4PlaHit.h -- This class is for plastic scintillator signal
// Created: Jan. 23, 2019, by Asia SUN, asia.rabbit@163.com
// Last Modified: Nov. 10, 2023 by Asia SUN

#ifndef EG4PlaHit_h
#define EG4PlaHit_h

#include "G4VHit.hh"
#include "G4Allocator.hh"
#include "G4RotationMatrix.hh"
#include "EG4Data.h"

class G4LogicalVolume;

using std::vector;
using std::map;
using std::string;

class EG4PlaHit : public G4VHit{
public:
  EG4PlaHit();
  EG4PlaHit(const EG4PlaHit &p);
  virtual ~EG4PlaHit();
  
  const EG4PlaHit &operator=(const EG4PlaHit &p);
  bool operator==(const EG4PlaHit &p) const;

  void *operator new(size_t);
  void operator delete(void *hit);

  virtual void Draw() override;
  virtual const map<G4String, G4AttDef> *GetAttDefs() const override;
  virtual vector<G4AttValue> *CreateAttValues() const override;
  virtual void Print() override;
  virtual void Initialize();

  void SetName(const string &name){ fName = name; }
  void SetParentId(int id){ fParentId = id; }
  void SetTrackId(int id){ fTrackId = id; }
  void SetHitType(int t){ fType = t; }
  void SetLayerId(int id){ fLayerId = id; }
  void SetStripId(int id){ fStripId = id; }
  void SetCharge(double c){ fCharge = c; }
  void SetMass(double m){ fMass = m; }
  void SetTime(double t){ fTime = t; }
  void SetKineticEnergy(double ek){ fEk = ek; }
  void SetEdep(double e){ fEdep = e; }
  void AddEdep(double e){ fEdep += e; }
  void SetTrkLen(double l){ fTrkLen = l; }
  void SetVelocity(double v){ fV = v; }
  void SetHitPos(G4ThreeVector pos){ fHitPos = pos; }
  void SetMomentum(G4ThreeVector p){ fP = p; }
  void SetLV(G4LogicalVolume *lv){ fLV = lv; }
  void SetPos(G4ThreeVector pos){ fPos = pos; }
  void SetRot(G4RotationMatrix rmat){ fRot = rmat; }

  const char *GetName() const{ return fName.data(); }
  int GetParentId() const{ return fParentId; }
  int GetTrackId() const{ return fTrackId; }
  int GetHitType() const{ return fType; }
  int GetLayerId() const{ return fLayerId; }
  int GetStripId() const{ return fStripId; }
  double GetCharge() const{ return fCharge; }
  double GetMass() const{ return fMass; }
  double GetTime() const{ return fTime; }
  double GetKineticEnergy() const{ return fEk; }
  double GetEdep() const{ return fEdep; }
  double GetTrkLen() const{ return fTrkLen; }
  double GetVelocity() const{ return fV; }
  G4ThreeVector GetHitPos() const{ return fHitPos; }
  G4ThreeVector GetPos() const{ return fPos; }
  G4ThreeVector GetMomentum() const{ return fP; }
  G4RotationMatrix GetRot() const{ return fRot; }
  G4LogicalVolume *GetLV() const{ return fLV; }

  void Assign(hit_t &t) const;

protected:
  int fParentId, fTrackId;
  int fType; // [0-primaries--1-charged-2ndaries--2-2ndary_neutron]
  int fLayerId, fStripId;
  string fName;
  double fCharge, fMass, fTime;
  G4ThreeVector fHitPos, fP;
  double fEk, fV, fEdep, fTrkLen;
  G4LogicalVolume *fLV;
  G4ThreeVector fPos; // just detector translation
  G4RotationMatrix fRot;

  static G4ThreadLocal G4Allocator<EG4PlaHit> *phAlloc;
};

#endif
